package logic

import (
	"context"
	"fmt"
	"strconv"

	"probe-users/internal/errorx"
	"probe-users/internal/model"
	"probe-users/internal/svc"
	"probe-users/internal/utils"
	"probe-users/pb/users"

	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
)

type ListUsersLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewListUsersLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListUsersLogic {
	return &ListUsersLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

// ListUsers 分页查询所有用户
func (l *ListUsersLogic) ListUsers(in *users.ListUsersRequest) (*users.ListUsersResponse, error) {
	// 1. 权限校验：仅管理员可查询
	if err := l.checkPermission(in.AdminToken); err != nil {
		return nil, err
	}

	// 2. 处理分页参数（默认值+边界限制）
	page, pageSize := l.parsePageParams(in.Page, in.PageSize)

	// 3. 查询用户总条数
	total, err := l.svcCtx.UserModel.Count(l.ctx)
	if err != nil {
		return nil, errors.Wrapf(err, "查询用户总数失败")
	}

	// 4. 分页查询用户列表
	userList, err := l.svcCtx.UserModel.FindPage(l.ctx, (page-1)*pageSize, pageSize)
	fmt.Println(userList)
	if err != nil {
		return nil, errors.Wrapf(err, "分页查询用户失败 [page=%d, pageSize=%d]", page, pageSize)
	}

	// 5. 格式化用户数据（补充角色名称、脱敏手机号、转换时间戳）
	respUsers, err := l.formatUsers(userList)
	if err != nil {
		return nil, errors.Wrapf(err, "格式化用户数据失败")
	}

	// 6. 计算总页数
	totalPage := l.calcTotalPage(total, pageSize)

	return &users.ListUsersResponse{
		Users:     respUsers,
		Total:     int32(total),
		Page:      int32(page),
		PageSize:  int32(pageSize),
		TotalPage: int32(totalPage),
	}, nil
}

// 权限校验：检查是否有user:list权限
func (l *ListUsersLogic) checkPermission(adminToken string) error {
	// 解析管理员Token
	claims, err := utils.ParseToken(adminToken, l.svcCtx.Config.JWTAuth.AccessSecret)
	if err != nil {
		return errorx.ErrInvalidToken
	}

	// Casbin权限检查
	sub := strconv.FormatInt(claims.RoleId, 10) // 角色ID转字符串
	hasPerm, err := l.svcCtx.Enforcer.Enforce(sub, "user", "list")
	if err != nil {
		return errorx.ErrPermissionDenied
	}
	if !hasPerm {
		return errorx.ErrListUsersPermissionDenied
	}
	return nil
}

// 解析分页参数（处理默认值和边界）
func (l *ListUsersLogic) parsePageParams(page, pageSize int32) (int, int) {
	// 页码默认1，最小1
	p := int(page)
	if p < 1 {
		p = 1
	}

	// 每页条数默认10，最小1，最大100
	ps := int(pageSize)
	if ps < 1 {
		ps = 10
	} else if ps > 100 {
		ps = 100
	}

	return p, ps
}

// 格式化用户数据（适配User消息体）
func (l *ListUsersLogic) formatUsers(modelUsers []*model.User) ([]*users.User, error) {
	var respUsers []*users.User
	for _, mu := range modelUsers {
		// 查询角色名称（补充role_name字段）
		role, err := l.svcCtx.RoleModel.FindOne(mu.RoleID)
		if err != nil {
			l.Logger.Errorf("用户ID=%d的角色ID=%d不存在", mu.ID, mu.RoleID)
			role = &model.Role{Name: "未知角色"} // 角色不存在时的默认值
		}

		// 手机号脱敏（保留前3位+后4位，中间用****代替）
		phone := mu.Phone
		// if len(phone) >= 7 {
		// 	phone = phone[:3] + "****" + phone[len(phone)-4:]
		// }

		// 时间戳转换（假设model中是time.Time类型，转为秒级时间戳）
		createdAt := mu.CreatedAt.Unix()
		updatedAt := mu.UpdatedAt.Unix()

		respUsers = append(respUsers, &users.User{
			Id:        mu.ID,
			Username:  mu.Username,
			Email:     mu.Email,
			Phone:     phone,
			Nickname:  mu.Nickname,
			RoleId:    mu.RoleID,
			RoleName:  role.Name,
			CreatedAt: createdAt,
			UpdatedAt: updatedAt,
		})
	}
	return respUsers, nil
}

// 计算总页数（向上取整）
func (l *ListUsersLogic) calcTotalPage(total int64, pageSize int) int {
	if total <= 0 {
		return 0
	}
	totalPage := int(total) / pageSize
	if int(total)%pageSize != 0 {
		totalPage++
	}
	return totalPage
}
